
#ifndef ARDP_DETECTOR
#define ARDP_DETECTOR

#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/objdetect/objdetect.hpp>
#include <iostream>

class ARDPDetector
{
//private vars
private:
cv::Mat temp;  
int mode;
int sizex, sizey;
cv::CascadeClassifier cascade;
cv::string windowName;

//public methods
public:
   ARDPDetector()
   {
     cv::Mat temp=cv::imread("temp5.png", CV_LOAD_IMAGE_GRAYSCALE);
     mode = 5;
     //for video use this or get actual values
     sizex=640; 
     sizey=360;
     //sizex=1366;
     //sizey=768;
   }
   
   void initialize(int image_sizex, int image_sizey)
   {
      windowName = "ARDrone Detection Application"; 
      cv::namedWindow(windowName, CV_WINDOW_NORMAL);
      sizex=image_sizex; sizey=image_sizey;
   }
   
   int setTemplate(const cv::Mat &Template)
   {
      if(Template.data)
	temp = Template;
      else { std::cout << "Can't read custom template!\n"; return 1;}
      return 0;
   }
   int setTemplate(int temp_use)
   {
    if(temp_use==0)//cross
       temp = cv::imread("temp5.png", CV_LOAD_IMAGE_GRAYSCALE);
    else if(temp_use==1)//H symbol
	temp = cv::imread("tempH1.png", CV_LOAD_IMAGE_GRAYSCALE);
    if(!temp.data)
    {	std::cout << "Cannot read template image!\n"; return 1; }
    return 0;
   }
   
   void setMode(int Mode)
   {
       mode = Mode;
       if(mode==5)
       {
	  if(!cascade.load("cascade3.xml"))
	    std::cout << "not loaded";
       }
   }
   
   int detect(char* frame, int &x, int &y, int &width, int &heigth)
   {
	try{
	   cv::Mat image(sizex, sizey, CV_8UC3, (uchar*)frame);
	   cv::cvtColor(image, image, CV_RGB2GRAY);
// 	   cv::namedWindow("test");
	   bool bFound = false;
	   if(mode==5)
	   {
	      std::vector<cv::Rect> obj;
	      cascade.detectMultiScale(image, obj, 1.1, 5, 0 | CV_HAAR_SCALE_IMAGE, cv::Size(20, 20));
	      //std::cout << "detecting...\n";
	      if(obj.size() != 0)
	      {
		  std::cout << "Found object!\n" << obj.size() << "\n";
		  bFound=true;
		  x = obj[0].x;
		  y = obj[0].y;
		  width = obj[0].width;
		  heigth = obj[0].height; 
		  cv::Point center( obj[0].x + obj[0].width*0.5, obj[0].y + obj[0].height*0.5 );
		  cv::ellipse(image, center, cv::Size( obj[0].width*0.5, obj[0].height*0.5), 0, 0, 360, cv::Scalar( 255, 0, 255 ), 4, 8, 0 );    
	      }
	   } 	   cv::imshow(windowName, image);
 	   cv::waitKey(1000/30);
	   if(bFound)
	     return 1;
	   return 0;
	   
	}catch(...)
	{
	    std::cout << "Oops! Exception caught when trying to detect object\n"; 
	}
   }
   
   int display(char* frame)
   {
	   cv::Mat image(sizex, sizey, CV_8UC3, (uchar*)frame);
	   cv::imshow(windowName, image);
	   cv::waitKey(1000/30);
	   return 0;
	    
   }
  
  
  
};

#endif